package com.atguigu.redis7.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * @author zhumq
 * @date 2024/7/28 23:57
 *
 * 布隆过滤器白名单初始化工具类，一开始就设置一部分数据为白名单所有，
 * 白名单业务默认规定：布隆过滤器有，redis是极大可能有。
 * 白名单：whitelistCustomer
 */
@Component
@Slf4j
public class BloomFilterInit
{
    @Resource
    private RedisTemplate redisTemplate;
    /**
     * 初始化方法，用于在系统启动后将特定客户添加到白名单中。
     * 通过布隆过滤器来存储白名单客户，以高效地识别是否为白名单客户。
     * 具体实现是将客户的唯一标识转换为哈希值，并将该哈希值对应的位置在布隆过滤器（这里使用Redis的Bitmap实现）中设置为1。
     *
     * @PostConstruct 注解表示该方法在类实例初始化后调用。
     */
    @PostConstruct//初始化白名单数据,暂时注释省的后台打印
    public void init()
    {
        //1 白名单客户加载到布隆过滤器 // 定义客户标识，这里以"customer:12"为例。
        String key = "customer:12";
        //2 计算hashValue,由于存在计算出来负数的可能，我们取绝对值 // 计算客户标识的哈希值，并取绝对值以确保值为正数。
        int hashValue = Math.abs(key.hashCode());
        //3 通过hashValue和2的32次方后取余，获得对应的下标坑位 // 根据哈希值计算在布隆过滤器中的索引位置，使用哈希值对2的32次方取余。
        long index = (long)(hashValue % Math.pow(2,32));
        // 记录客户标识对应的布隆过滤器索引位置，便于调试和排查问题。
        log.info(key+" 对应的坑位index:{}",index);
        //4 设置redis里面的bitmap对应类型白名单：whitelistCustomer的坑位，将该值设置为1 // 在Redis的布隆过滤器中，将对应索引位置设置为1，表示该客户是白名单客户。
        redisTemplate.opsForValue().setBit("whitelistCustomer",index,true);
        
    }
}
